<template>
  <view class="voice-recognition">
    <!-- 语音识别控制区域 -->
    <view class="control-section">
      <view class="record-controls">
        <button 
          class="record-btn" 
          :class="{ 'recording': isRecording, 'disabled': !isSupported }"
          @click="toggleRecording"
          :disabled="!isSupported"
        >
          <text class="btn-icon">{{ isRecording ? '⏹️' : '🎤' }}</text>
          <text class="btn-text">{{ isRecording ? '停止录音' : '开始录音' }}</text>
        </button>
        
        <button 
          class="clear-btn" 
          @click="clearTranscript"
          :disabled="!transcript"
        >
          清空文本
        </button>
      </view>
      
      <!-- 语言选择 -->
      <view class="language-selector">
        <picker 
          :value="languageIndex" 
          :range="languages" 
          range-key="name"
          @change="onLanguageChange"
        >
          <view class="picker-text">
            语言: {{ languages[languageIndex].name }}
          </view>
        </picker>
      </view>
    </view>

    <!-- 状态显示 -->
    <view class="status-section" v-if="status">
      <text class="status-text" :class="statusClass">{{ status }}</text>
    </view>

    <!-- 转录结果显示 -->
    <view class="transcript-section">
      <view class="transcript-header">
        <text class="section-title">转录结果</text>
        <text class="char-count">{{ transcript.length }} 字符</text>
      </view>
      
      <textarea 
        class="transcript-text"
        v-model="transcript"
        placeholder="语音转文字结果将显示在这里..."
        :maxlength="5000"
      />
    </view>

    <!-- 音频播放区域 -->
    <view class="audio-section" v-if="audioUrl">
      <view class="audio-header">
        <text class="section-title">录音播放</text>
        <text class="audio-duration">{{ formatDuration(audioDuration) }}</text>
      </view>
      
      <view class="audio-controls">
        <button class="play-btn" @click="toggleAudioPlay">
          {{ isPlaying ? '⏸️ 暂停' : '▶️ 播放' }}
        </button>
        <button class="download-btn" @click="downloadAudio">
          💾 下载
        </button>
      </view>
      
      <audio 
        ref="audioPlayer"
        :src="audioUrl"
        @loadedmetadata="onAudioLoaded"
        @ended="onAudioEnded"
        @timeupdate="onTimeUpdate"
      />
      
      <view class="progress-bar" v-if="audioDuration > 0">
        <view 
          class="progress-fill" 
          :style="{ width: (currentTime / audioDuration * 100) + '%' }"
        />
      </view>
    </view>

    <!-- 文件上传区域 -->
    <view class="upload-section">
      <view class="upload-header">
        <text class="section-title">上传音频文件</text>
      </view>
      
      <button class="upload-btn" @click="selectAudioFile">
        📁 选择音频文件
      </button>
      
      <view class="supported-formats">
        支持格式: MP3, WAV, M4A, OGG
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'VoiceRecognition',
  
  props: {
    // 是否自动开始识别
    autoStart: {
      type: Boolean,
      default: false
    },
    // 默认语言
    defaultLanguage: {
      type: String,
      default: 'zh-CN'
    },
    // 最大录音时长（秒）
    maxDuration: {
      type: Number,
      default: 300
    },
    // 是否连续识别
    continuous: {
      type: Boolean,
      default: true
    }
  },
  
  data() {
    return {
      // 语音识别相关
      recognition: null,
      isRecording: false,
      isSupported: false,
      transcript: '',
      interimTranscript: '',
      
      // 音频录制相关
      mediaRecorder: null,
      audioChunks: [],
      audioUrl: '',
      audioDuration: 0,
      currentTime: 0,
      isPlaying: false,
      
      // 状态管理
      status: '',
      statusClass: '',
      
      // 语言配置
      languageIndex: 0,
      languages: [
        { code: 'zh-CN', name: '中文(普通话)' },
        { code: 'en-US', name: 'English (US)' },
        { code: 'ja-JP', name: '日本語' },
        { code: 'ko-KR', name: '한국어' },
        { code: 'fr-FR', name: 'Français' },
        { code: 'de-DE', name: 'Deutsch' },
        { code: 'es-ES', name: 'Español' },
        { code: 'ru-RU', name: 'Русский' }
      ]
    }
  },
  
  computed: {
    currentLanguage() {
      return this.languages[this.languageIndex].code;
    }
  },
  
  mounted() {
    this.initVoiceRecognition();
    this.setDefaultLanguage();
  },
  
  beforeDestroy() {
    this.cleanup();
  },
  
  methods: {
    // 初始化语音识别
    initVoiceRecognition() {
      if ('webkitSpeechRecognition' in window) {
        this.recognition = new webkitSpeechRecognition();
        this.isSupported = true;
        this.setupRecognition();
      } else if ('SpeechRecognition' in window) {
        this.recognition = new SpeechRecognition();
        this.isSupported = true;
        this.setupRecognition();
      } else {
        this.isSupported = false;
        this.setStatus('您的浏览器不支持语音识别功能', 'error');
      }
    },
    
    // 配置语音识别
    setupRecognition() {
      if (!this.recognition) return;
      
      this.recognition.continuous = this.continuous;
      this.recognition.interimResults = true;
      this.recognition.lang = this.currentLanguage;
      
      this.recognition.onstart = () => {
        this.setStatus('正在监听...', 'listening');
      };
      
      this.recognition.onresult = (event) => {
        let interimTranscript = '';
        let finalTranscript = '';
        
        for (let i = event.resultIndex; i < event.results.length; i++) {
          const transcript = event.results[i][0].transcript;
          if (event.results[i].isFinal) {
            finalTranscript += transcript;
          } else {
            interimTranscript += transcript;
          }
        }
        
        this.interimTranscript = interimTranscript;
        if (finalTranscript) {
          this.transcript += finalTranscript;
          this.$emit('transcript-update', this.transcript);
        }
      };
      
      this.recognition.onerror = (event) => {
        console.error('语音识别错误:', event.error);
        this.handleRecognitionError(event.error);
      };
      
      this.recognition.onend = () => {
        this.isRecording = false;
        this.setStatus('录音已停止', 'stopped');
        this.stopMediaRecorder();
      };
    },
    
    // 设置默认语言
    setDefaultLanguage() {
      const index = this.languages.findIndex(lang => lang.code === this.defaultLanguage);
      if (index !== -1) {
        this.languageIndex = index;
      }
    },
    
    // 切换录音状态
    async toggleRecording() {
      if (!this.isSupported) return;
      
      if (this.isRecording) {
        this.stopRecording();
      } else {
        await this.startRecording();
      }
    },
    
    // 开始录音
    async startRecording() {
      try {
        // 请求麦克风权限
        const stream = await navigator.mediaDevices.getUserMedia({ 
          audio: {
            echoCancellation: true,
            noiseSuppression: true,
            sampleRate: 44100
          } 
        });
        
        // 开始音频录制
        this.startMediaRecorder(stream);
        
        // 开始语音识别
        this.recognition.lang = this.currentLanguage;
        this.recognition.start();
        this.isRecording = true;
        
        this.$emit('recording-start');
        
      } catch (error) {
        console.error('开始录音失败:', error);
        this.setStatus('无法访问麦克风，请检查权限设置', 'error');
      }
    },
    
    // 停止录音
    stopRecording() {
      if (this.recognition && this.isRecording) {
        this.recognition.stop();
      }
      this.isRecording = false;
      this.$emit('recording-stop');
    },
    
    // 开始媒体录制
    startMediaRecorder(stream) {
      this.audioChunks = [];
      this.mediaRecorder = new MediaRecorder(stream, {
        mimeType: 'audio/webm;codecs=opus'
      });
      
      this.mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          this.audioChunks.push(event.data);
        }
      };
      
      this.mediaRecorder.onstop = () => {
        const audioBlob = new Blob(this.audioChunks, { type: 'audio/webm' });
        this.audioUrl = URL.createObjectURL(audioBlob);
        this.$emit('audio-recorded', audioBlob);
        
        // 停止所有音频轨道
        stream.getTracks().forEach(track => track.stop());
      };
      
      this.mediaRecorder.start(1000); // 每秒收集一次数据
    },
    
    // 停止媒体录制
    stopMediaRecorder() {
      if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
        this.mediaRecorder.stop();
      }
    },
    
    // 处理识别错误
    handleRecognitionError(error) {
      let message = '语音识别出错';
      
      switch (error) {
        case 'no-speech':
          message = '未检测到语音，请重试';
          break;
        case 'audio-capture':
          message = '无法捕获音频，请检查麦克风';
          break;
        case 'not-allowed':
          message = '麦克风权限被拒绝';
          break;
        case 'network':
          message = '网络错误，请检查网络连接';
          break;
        case 'service-not-allowed':
          message = '语音识别服务不可用';
          break;
      }
      
      this.setStatus(message, 'error');
    },
    
    // 设置状态
    setStatus(message, type = 'info') {
      this.status = message;
      this.statusClass = `status-${type}`;
      
      // 3秒后清除状态
      setTimeout(() => {
        if (this.status === message) {
          this.status = '';
          this.statusClass = '';
        }
      }, 3000);
    },
    
    // 清空转录文本
    clearTranscript() {
      this.transcript = '';
      this.interimTranscript = '';
      this.$emit('transcript-clear');
    },
    
    // 语言切换
    onLanguageChange(e) {
      this.languageIndex = e.detail.value;
      if (this.recognition) {
        this.recognition.lang = this.currentLanguage;
      }
      this.$emit('language-change', this.currentLanguage);
    },
    
    // 音频播放控制
    toggleAudioPlay() {
      const audio = this.$refs.audioPlayer;
      if (!audio) return;
      
      if (this.isPlaying) {
        audio.pause();
      } else {
        audio.play();
      }
    },
    
    // 音频加载完成
    onAudioLoaded() {
      const audio = this.$refs.audioPlayer;
      if (audio) {
        this.audioDuration = audio.duration;
      }
    },
    
    // 音频播放结束
    onAudioEnded() {
      this.isPlaying = false;
      this.currentTime = 0;
    },
    
    // 音频时间更新
    onTimeUpdate() {
      const audio = this.$refs.audioPlayer;
      if (audio) {
        this.currentTime = audio.currentTime;
        this.isPlaying = !audio.paused;
      }
    },
    
    // 下载音频
    downloadAudio() {
      if (!this.audioUrl) return;
      
      const link = document.createElement('a');
      link.href = this.audioUrl;
      link.download = `recording_${new Date().getTime()}.webm`;
      link.click();
    },
    
    // 选择音频文件
    selectAudioFile() {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = 'audio/*';
      input.onchange = (e) => {
        const file = e.target.files[0];
        if (file) {
          this.handleAudioFile(file);
        }
      };
      input.click();
    },
    
    // 处理音频文件
    handleAudioFile(file) {
      const url = URL.createObjectURL(file);
      this.audioUrl = url;
      this.setStatus(`已加载音频文件: ${file.name}`, 'success');
      this.$emit('audio-file-loaded', file);
    },
    
    // 格式化时长
    formatDuration(seconds) {
      if (!seconds || isNaN(seconds)) return '00:00';
      
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
    },
    
    // 清理资源
    cleanup() {
      if (this.recognition) {
        this.recognition.stop();
      }
      if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
        this.mediaRecorder.stop();
      }
      if (this.audioUrl) {
        URL.revokeObjectURL(this.audioUrl);
      }
    }
  }
}
</script>

<style scoped>
.voice-recognition {
  padding: 20px;
  max-width: 800px;
  margin: 0 auto;
}

/* 控制区域 */
.control-section {
  margin-bottom: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
}

.record-controls {
  display: flex;
  gap: 15px;
  margin-bottom: 15px;
  align-items: center;
}

.record-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  background: #007bff;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.record-btn:hover {
  background: #0056b3;
  transform: translateY(-2px);
}

.record-btn.recording {
  background: #dc3545;
  animation: pulse 1.5s infinite;
}

.record-btn.disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.clear-btn {
  padding: 12px 20px;
  background: #6c757d;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.3s ease;
}

.clear-btn:hover:not(:disabled) {
  background: #545b62;
}

.clear-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.language-selector {
  margin-top: 15px;
}

.picker-text {
  padding: 10px 15px;
  background: white;
  border: 1px solid #ddd;
  border-radius: 6px;
  cursor: pointer;
}

/* 状态显示 */
.status-section {
  margin-bottom: 20px;
  text-align: center;
}

.status-text {
  padding: 10px 20px;
  border-radius: 6px;
  font-weight: 500;
}

.status-listening {
  background: #d4edda;
  color: #155724;
}

.status-error {
  background: #f8d7da;
  color: #721c24;
}

.status-success {
  background: #d1ecf1;
  color: #0c5460;
}

.status-stopped {
  background: #fff3cd;
  color: #856404;
}

/* 转录结果 */
.transcript-section {
  margin-bottom: 20px;
}

.transcript-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.section-title {
  font-size: 18px;
  font-weight: 600;
  color: #333;
}

.char-count {
  color: #666;
  font-size: 14px;
}

.transcript-text {
  width: 100%;
  min-height: 120px;
  padding: 15px;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  font-size: 16px;
  line-height: 1.5;
  resize: vertical;
  transition: border-color 0.3s ease;
}

.transcript-text:focus {
  outline: none;
  border-color: #007bff;
}

/* 音频区域 */
.audio-section {
  margin-bottom: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
}

.audio-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.audio-duration {
  color: #666;
  font-family: monospace;
}

.audio-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.play-btn, .download-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.3s ease;
}

.play-btn {
  background: #28a745;
  color: white;
}

.play-btn:hover {
  background: #218838;
}

.download-btn {
  background: #17a2b8;
  color: white;
}

.download-btn:hover {
  background: #138496;
}

.progress-bar {
  width: 100%;
  height: 4px;
  background: #e9ecef;
  border-radius: 2px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: #007bff;
  transition: width 0.1s ease;
}

/* 上传区域 */
.upload-section {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  text-align: center;
}

.upload-header {
  margin-bottom: 15px;
}

.upload-btn {
  padding: 12px 24px;
  background: #28a745;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: background 0.3s ease;
}

.upload-btn:hover {
  background: #218838;
}

.supported-formats {
  margin-top: 10px;
  color: #666;
  font-size: 14px;
}

/* 动画效果 */
@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

/* 响应式设计 */
@media (max-width: 768px) {
  .voice-recognition {
    padding: 15px;
  }
  
  .record-controls {
    flex-direction: column;
    align-items: stretch;
  }
  
  .record-btn, .clear-btn {
    width: 100%;
    justify-content: center;
  }
  
  .audio-controls {
    flex-direction: column;
  }
  
  .play-btn, .download-btn {
    width: 100%;
  }
}
</style>